package cn.shiwei.hr.service.impl;

import cn.shiwei.hr.domain.CourseType;
import cn.shiwei.hr.mapper.CourseTypeMapper;
import cn.shiwei.hr.service.ICourseTypeService;
import cn.shiwei.hr.vo.CrumbVO;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

import static cn.shiwei.hr.constants.RedisConstants.COURSE_CATEGORY_CACHE_PREFIX;
import static cn.shiwei.hr.constants.RedisConstants.TREE_CLASSIFICATION_OF_ALL_COURSES;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author 1363732197@qq.com
 * @since 2021-11-26
 */
@Service
@CacheConfig(cacheNames = COURSE_CATEGORY_CACHE_PREFIX)
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {

/*    @Override
    public List<CourseType> selectTreeData() {
        List<CourseType> courseTypes = baseMapper.selectList(null);
        List<CourseType> courseTreeTypes = new ArrayList<>();
        courseTypes.forEach(courseType -> {
            if (courseType.getPid() == 0){
                // 表明为第一级
                courseTreeTypes.add(courseType);
            } else {
                // 表明为其他级, 此处为其他级设置好父级/子级
                for (CourseType type : courseTypes) {
                    if (courseType.getPid().equals(type.getId())){
                        type.getChildren().add(courseType);
                        break;
                    }
                }
            }
        });
        return  courseTreeTypes;
    }*/

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Override
    @Cacheable(key = TREE_CLASSIFICATION_OF_ALL_COURSES)
    public List<CourseType> selectTreeData() {
//        List<CourseType> treeData = (List<CourseType>)redisTemplate.opsForValue().get(TREE_CLASSIFICATION_OF_ALL_COURSES);
//        if (treeData != null) {
//            // 缓存中有数据, 返回缓存数据
//            return treeData;
//        }
//        // 缓存中没数据, 从数据库查询在存入缓存
//        treeData = this.getTreeData();
//        redisTemplate.opsForValue().set(TREE_CLASSIFICATION_OF_ALL_COURSES, treeData, 12, TimeUnit.HOURS);
        return this.getTreeData(); // treeData
    }

    @Override
    public void updateByIdsToTotalCount(List<String> types, int count) {
        baseMapper.updateByIdsToTotalCount(types, count);
    }

    @Override
    public List<CrumbVO> selectCrumbs(Long id) {

        ArrayList<CrumbVO> crumbs = new ArrayList<>();
        CourseType courseType = selectById(id);
        Arrays.stream(courseType.getPath().split("\\.")).forEach(typeId ->{

            CrumbVO crumbVO = new CrumbVO();

            CourseType currentType = selectById(typeId);
            Wrapper<CourseType> wrapper = new EntityWrapper<>();
            wrapper.eq("pid", currentType.getPid());

            crumbVO.setOtherCourseTypes(selectList(wrapper));
            crumbVO.setOwnerCourseType(currentType);

            crumbs.add(crumbVO);

        });


        return crumbs;
    }

    // 优化
    public List<CourseType> getTreeData() {
        List<CourseType> courseTypes = baseMapper.selectList(null);
        List<CourseType> courseTreeTypes = new ArrayList<>();
        Map<Long, CourseType> collect = courseTypes.stream().collect(Collectors.toMap(CourseType::getId, courseType -> courseType));
        courseTypes.forEach(courseType -> {
            if (courseType.getPid() == 0) {
                // 表明为第一级
                courseTreeTypes.add(courseType);
            } else {
                // courseType的pid 等于父级的 id, collect的key是id
                collect.get(courseType.getPid()).getChildren().add(courseType);
            }
        });
        return courseTreeTypes;
    }

    @Override
    @CacheEvict(key = TREE_CLASSIFICATION_OF_ALL_COURSES)
    public boolean insert(CourseType entity) {
        boolean insert = super.insert(entity);
//        if (insert){
//            redisTemplate.delete(TREE_CLASSIFICATION_OF_ALL_COURSES);
//        }
        return insert;
    }

    @Override
    @CacheEvict(key = TREE_CLASSIFICATION_OF_ALL_COURSES)
    public boolean deleteById(Serializable id) {
        boolean b = super.deleteById(id);
//        if (b) {
//            redisTemplate.delete(TREE_CLASSIFICATION_OF_ALL_COURSES);
//        }
        return b;
    }

    @Override
    @CacheEvict(key = TREE_CLASSIFICATION_OF_ALL_COURSES)
    public boolean updateById(CourseType entity) {
        boolean b = super.updateById(entity);
//        if (b) {
//            redisTemplate.delete(TREE_CLASSIFICATION_OF_ALL_COURSES);
//        }
        return b;
    }

    //    private void getTreeData(long[] pids) {
//        List<CourseType> types = baseMapper.selectBatchPID(pids);
//        if (!CollectionUtils.isEmpty(types)){
//            long[] longs = types.stream().mapToLong(type -> {
//                courseTypes.add(type);
//                return type.getId();
//            }).toArray();
//            getTreeData(longs);
//        }else {
//            return;
//        }
//    }

}
